'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'                                                                         '
'   Copyright (C) 2008 by Daniel Danopia								  '
'   me.L0GG3R@danopia.net												  '
'                                                                         '
'   This program is free software; you can redistribute it and/or modify  '
'   it under the terms of the GNU General Public License as published by  '
'   the Free Software Foundation; either version 2 of the License, or     '
'   (at your option) any later version.                                   '
'                                                                         '
'   This program is distributed in the hope that it will be useful,       '
'   but WITHOUT ANY WARRANTY; without even the implied warranty of        '
'   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         '
'   GNU General Public License for more details.                          '
'                                                                         '
'   You should have received a copy of the GNU General Public License     '
'   along with this program; if not, write to the                         '
'   Free Software Foundation, Inc.,                                       '
'   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             '
'                                                                         '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

#Const MySQL = False
#Const Chart = False
#If Chart Then
Imports WebChart
#End If
Public Class Form1
    Public Socket As New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
    Public OpenedTabs As New Dictionary(Of String, TabPage)
    Public XMLSettings As New Xml.XmlDocument()
    Public XMLPath As String = My.Application.Info.AssemblyName & ".config.xml"
    Public CurrentEvents As New Dictionary(Of String, IO.StreamWriter)
    Public CurrentDate As New Date(Now.Year, Now.Month, Now.Day)
    Public EventStart As New Dictionary(Of IO.StreamWriter, Date)
    Public NickList As New Dictionary(Of String, List(Of String))
    Public MyNick As String = ""
    Public ColorRequests As New Generic.Dictionary(Of String, ColorRequest)
    Public AntiFlood As Double = 0
    Public CurrentTimeStamp As Date = Nothing
    Public CurrentTimeStampID As Integer = Nothing
    Public Client As New Net.WebClient()
#If Chart Then
    Public DoneCharts As Boolean = False
#End If
    Public ReadOnly UnixEpoche As New Date(1970, 1, 1)
    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Send("QUIT :" & Config("defaultquit"))
        For Each Tab As TabPage In tbcLogs.TabPages
            If TypeOf Tab.Tag Is IO.StreamWriter Then
                CType(Tab.Tag, IO.StreamWriter).WriteLine("</body></html>")
                CType(Tab.Tag, IO.StreamWriter).Close()
            End If
        Next
        For Each SpecialEvent As IO.StreamWriter In CurrentEvents.Values
            SpecialEvent.WriteLine("<p style=""color:#090;"">* Special event log stopped @ " & Now.ToLongTimeString & ", about " & Now.Subtract(EventStart(SpecialEvent)).Minutes & " after it was started (Why? I'm shutting down, that's why)</p></body></html>")
            SpecialEvent.Close()
        Next
    End Sub
    Public Function Config(ByVal Name As String) As String
        Return XMLSettings.SelectSingleNode("config/setting[@name='" & Name & "']").InnerText()
    End Function
    Public Property NickColor(ByVal Nick As String, Optional ByVal DefaultColor As String = "") As String
        Get
            Dim Matches As Xml.XmlNodeList = XMLSettings.SelectNodes("config/colors/color[@nick='" & Nick & "']")
            If Matches.Count > 0 Then
                Return Matches(0).InnerText()
            Else
                Return DefaultColor
            End If
        End Get
        Set(ByVal value As String)
            Dim Matches As Xml.XmlNodeList = XMLSettings.SelectNodes("config/colors/color[@nick='" & Nick & "']")
            If Matches.Count > 0 Then
                Matches(0).InnerText = value
            Else
                Dim Node As Xml.XmlElement = XMLSettings.CreateElement("color")
                Node.SetAttribute("nick", value)
                Node.InnerText = value
                XMLSettings.SelectSingleNode("config/colors").AppendChild(Node)
            End If
        End Set
    End Property
    Public Function Capab(ByVal Name As String) As Boolean
        Dim Matches As Xml.XmlNodeList = XMLSettings.SelectNodes("config/capabilities/@" & Name)
        If Matches.Count > 0 Then
            Return Boolean.Parse(Matches(0).InnerText())
        Else
            Return False
        End If
    End Function
#If Chart Then
    Public Sub UploadCharts()
        picChart1.Image = UploadChart(tabChart1.Tag, "overall")
        picChart2.Image = UploadChart(tabChart2.Tag, "server1")
        picChart3.Image = UploadChart(tabChart3.Tag, "server2")
    End Sub
    Public Function UploadChart(ByVal Engine As ChartEngine, ByVal Filename As String) As Bitmap
        If Engine.Charts Is Nothing Then Engine.Charts = New ChartCollection(Engine)
        UploadChart = Engine.GetBitmap()
        Dim memStream As New System.IO.MemoryStream()
        UploadChart.Save(memStream, System.Drawing.Imaging.ImageFormat.Png)
        Client.UploadData(New Uri(Config("graphpath") & Filename & ".png"), memStream.GetBuffer)
    End Function
#End If
    Public Function ConvertTimestamp(ByVal Native As Date) As Integer
        Return Math.Floor(Native.Subtract(UnixEpoche).TotalSeconds)
    End Function
    Public Function ConvertTimestamp(ByVal Unix As Integer) As Date
        Return UnixEpoche.AddSeconds(Unix)
    End Function
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim IsNext As Boolean = False
        For Each Arg As String In My.Application.CommandLineArgs
            If IsNext Then
                XMLPath = Arg
                IsNext = False
            ElseIf Arg.ToLower = "--config" Then
                IsNext = True
            End If
        Next
        XMLSettings.Load(XMLPath)
#If Chart Then
        StartCharts()
        UploadCharts()
#Else
        tbcLogs.TabPages.Remove(tabChart1)
        tbcLogs.TabPages.Remove(tabChart2)
        tbcLogs.TabPages.Remove(tabChart3)
#End If
#If MySQL Then
        Database.ReloadConfig()
        Database.Connect()
        Database.LoadTables()
#End If
        Socket.Connect(Config("server"), UShort.Parse(Config("port")))
        If Capab("pass") Then Send("PASS " & Config("identpass"))
        Send("NICK " & Config("nick"))
        Send("USER " & Config("nick") & " localhost 0.0.0.0 :" & Config("description"))
        MyNick = Config("nick")
        BackgroundWorker1.RunWorkerAsync()
    End Sub
#If Chart Then
    Sub StartCharts()
        Dim wcEng As New ChartEngine()
        tabChart1.Tag = wcEng
        wcEng.Size = New Size(600, 600)
        Dim wcCharts As New ChartCollection(wcEng)
        wcEng.Charts = wcCharts
        Dim slChart As Chart = New SmoothLineChart()
        slChart.Line.Color = Color.Red
        slChart.Legend = "Servers"
        slChart.Name = "Servers"
        slChart.ShowLineMarkers = False
        slChart.ShowLegend = True
        slChart.DataLabels.Visible = False
        slChart.Shadow.Visible = True
        wcCharts.Add(slChart)
        slChart = New SmoothLineChart()
        slChart.Line.Color = Color.Blue
        slChart.Legend = "Opers"
        slChart.Name = "Opers"
        slChart.ShowLineMarkers = False
        slChart.ShowLegend = True
        slChart.DataLabels.Visible = False
        slChart.Shadow.Visible = True
        wcCharts.Add(slChart)
        slChart = New SmoothLineChart()
        slChart.Line.Color = Color.DarkGray
        slChart.Legend = "Users"
        slChart.Name = "Users"
        slChart.ShowLineMarkers = False
        slChart.ShowLegend = True
        slChart.DataLabels.Visible = False
        slChart.Shadow.Visible = True
        wcCharts.Add(slChart)
        slChart = New SmoothLineChart()
        slChart.Line.Color = Color.Green
        slChart.Legend = "Channels"
        slChart.Name = "Channels"
        slChart.ShowLineMarkers = False
        slChart.ShowLegend = True
        slChart.DataLabels.Visible = False
        slChart.Shadow.Visible = True
        wcCharts.Add(slChart)
        Dim myFont As New System.Drawing.Font("Tahoma", 10)
        wcEng.XTitle = New ChartText()
        wcEng.HasChartLegend = True
        wcEng.Legend.Width = 34
        wcEng.Legend.Position = LegendPosition.Bottom
        wcEng.Legend.Border.Color = Color.DarkGray
        wcEng.Border.Color = Color.DarkGray
        wcEng.GridLines = WebChart.GridLines.Horizontal
        Dim horizontalFormat As New StringFormat()
        horizontalFormat.Alignment = StringAlignment.Center
        horizontalFormat.LineAlignment = StringAlignment.Far
        wcEng.XTitle.StringFormat = horizontalFormat
        wcEng.XTitle.Text = "Datapoint"
        wcEng.XTitle.Font = myFont
        wcEng.YTitle = New ChartText()
        wcEng.YTitle.Font = myFont
        Dim verticalFormat As New StringFormat()
        verticalFormat.FormatFlags = StringFormatFlags.DirectionVertical
        verticalFormat.Alignment = StringAlignment.Center
        wcEng.YTitle.StringFormat = verticalFormat
        wcEng.YTitle.Text = ""
        wcEng.Title = New ChartText()
        wcEng.Title.ForeColor = Color.White
        wcEng.Title.Font = New Font("Academy Engraved LET", 14, FontStyle.Bold)
        wcEng.Title.Text = "DevNode Stats"
        wcEng.ShowXValues = True
        wcEng.ShowYValues = True
        wcEng.Padding = 10
        wcEng.ChartPadding = 25
        wcEng.Background.Type = InteriorType.LinearGradient
        wcEng.Background.EndPoint = New Point(600, 600)
        wcEng.Background.Color = Color.FromArgb(70, Color.DarkBlue)
        wcEng.PlotBackground.Color = Color.Beige

        wcEng = New ChartEngine()
        tabChart2.Tag = wcEng
        wcEng.Size = New Size(600, 600)
        myFont = New System.Drawing.Font("Tahoma", 8)
        wcEng.XTitle = New ChartText()
        wcEng.HasChartLegend = True
        wcEng.Legend.Width = 74
        wcEng.Legend.Position = LegendPosition.Bottom
        wcEng.Legend.Border.Color = Color.DarkGray
        wcEng.Border.Color = Color.DarkGray
        wcEng.GridLines = WebChart.GridLines.Horizontal
        horizontalFormat = New StringFormat()
        horizontalFormat.Alignment = StringAlignment.Center
        horizontalFormat.LineAlignment = StringAlignment.Far
        wcEng.XTitle.StringFormat = horizontalFormat
        wcEng.XTitle.Text = "Datapoint"
        wcEng.XTitle.Font = myFont
        wcEng.YTitle = New ChartText()
        wcEng.YTitle.Font = myFont
        verticalFormat = New StringFormat()
        verticalFormat.FormatFlags = StringFormatFlags.DirectionVertical
        verticalFormat.Alignment = StringAlignment.Center
        wcEng.YTitle.StringFormat = verticalFormat
        wcEng.YTitle.Text = "Users"
        wcEng.Title = New ChartText()
        wcEng.Title.ForeColor = Color.White
        wcEng.Title.Font = New Font("Academy Engraved LET", 14, FontStyle.Bold)
        wcEng.Title.Text = "DevNode Users by Server"
        wcEng.ShowXValues = True
        wcEng.ShowYValues = True
        wcEng.Padding = 10
        wcEng.ChartPadding = 25
        wcEng.Background.Type = InteriorType.LinearGradient
        wcEng.Background.EndPoint = New Point(600, 600)
        wcEng.Background.Color = Color.FromArgb(70, Color.DarkBlue)
        wcEng.PlotBackground.Color = Color.Beige

        wcEng = New ChartEngine()
        tabChart3.Tag = wcEng
        wcEng.Size = New Size(600, 600)
        wcCharts = New ChartCollection(wcEng)
        wcEng.Charts = wcCharts
        slChart = New PieChart()
        slChart.Name = "Servers"
        wcEng.Charts.Add(slChart)
        slChart.Fill.Color = Color.Red
        slChart.Legend = "Servers"
        slChart.ShowLegend = True
        slChart.DataLabels.Visible = True
        slChart.DataLabels.ShowXTitle = False
        slChart.DataLabels.ShowZeroValues = False
        slChart.Shadow.Visible = False
        CType(slChart, PieChart).Explosion = 20
        myFont = New System.Drawing.Font("Tahoma", 8)
        wcEng.HasChartLegend = True
        wcEng.Legend.Width = 74
        wcEng.Legend.Position = LegendPosition.Bottom
        wcEng.Legend.Border.Color = Color.DarkGray
        wcEng.Border.Color = Color.DarkGray
        wcEng.Title = New ChartText()
        wcEng.Title.ForeColor = Color.White
        wcEng.Title.Font = New Font("Academy Engraved LET", 14, FontStyle.Bold)
        wcEng.Title.Text = "DevNode Users by Server"
        wcEng.ShowXValues = True
        wcEng.ShowYValues = True
        wcEng.Padding = 10
        wcEng.ChartPadding = 10
        wcEng.Background.Type = InteriorType.LinearGradient
        wcEng.Background.EndPoint = New Point(600, 600)
        wcEng.Background.Color = Color.FromArgb(70, Color.DarkBlue)
        wcEng.PlotBackground.Color = Color.Beige
    End Sub
#End If
    Public Sub Send(ByVal Data As String)
        Try
            If tmrAntiFlood.Enabled Then
                If AntiFlood < 4 Then
                    Socket.Send(System.Text.Encoding.ASCII.GetBytes(Data.Replace(vbCr, "").Replace(vbLf, "") & vbCrLf))
                    Log(">>> " & Data, "Raw")
                ElseIf AntiFlood < 5 Then
                    Socket.Send(System.Text.Encoding.ASCII.GetBytes("PRIVMSG #l0gg3r :I spy a flood" & vbCrLf))
                    Log("Flood prevented send of this packet: " & Data, "Info")
                Else
                    Log("A big flood value (" & AntiFlood & " prevented send of this packet: " & Data, "Info")
                End If
                AntiFlood += 1 + (Data.Length / 256)
            Else
                Socket.Send(System.Text.Encoding.ASCII.GetBytes(Data.Replace(vbCr, "").Replace(vbLf, "") & vbCrLf))
            End If
        Catch ex As Exception
            Log("Error sending packet", "Error")
        End Try
    End Sub
    Public Sub AddTab(ByVal Name As String)
        If OpenedTabs.ContainsKey(Name.ToLower) Then Exit Sub
        Dim Tab As New TabPage(Name)
        Tab.UseVisualStyleBackColor = True
        Dim Browser As New WebBrowser()
        Browser.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Browser.Location = New System.Drawing.Point(3, 3)
        Browser.Size = Drawing.Size.Subtract(tbcLogs.Size, New Drawing.Size(14, 32))
        Browser.Navigate("about:blank")
        Browser.Document.Write("<html><head><title>IRC Log from " & Name & " - Captured by " & Config("nick") & "</title><style>" & Config("screencss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & Name & " and logged by " & Config("nick") & "</p>" & vbNewLine & "</body></html>")
        Tab.Controls.Add(Browser)
        Tab.Tag = OpenWriter(Name)
        tbcLogs.Controls.Add(Tab)
        OpenedTabs.Add(Name.ToLower, Tab)
    End Sub
    Public Function OpenWriter(ByVal Name As String) As IO.StreamWriter
        Dim Path As String = String.Format(IO.Path.Combine(My.Application.Info.DirectoryPath, Config("logpath")), Name.Trim("#"), Now.Year, MonthName(Now.Month, True).ToLower) & Now.Day & "." & Config("extension")
        Dim Dirs() As String = Path.Substring(3, Path.LastIndexOfAny(New Char() {"/"c, "\"c}) - 3).Split("/"c, "\"c)
        Dim Dir As String = Path.Substring(0, 2)
        For Each SubDir As String In Dirs
            Dir &= "/" & SubDir
            If Not IO.Directory.Exists(Dir) Then IO.Directory.CreateDirectory(Dir)
        Next
        If IO.File.Exists(Path) Then
            Dim TempPath As String = String.Format(IO.Path.Combine(My.Application.Info.DirectoryPath, Config("logpath")), Name.Trim("#"), Now.Year, MonthName(Now.Month, True).ToLower) & Now.Day & "{0}." & Config("extension")
            For i As Integer = 1 To 25
                If Not IO.File.Exists(String.Format(TempPath, Chr(Asc("a") + i))) Then
                    Path = String.Format(TempPath, Chr(Asc("a") + i))
                    Exit For
                End If
            Next
        End If
        OpenWriter = New IO.StreamWriter(Path, False)
        OpenWriter.AutoFlush = True
        OpenWriter.WriteLine("<html><head><title>IRC Log from " & Name & " - Captured by " & Config("nick") & "</title><style>" & Config("filecss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & Name & " and logged by " & Config("nick") & "</p>" & vbNewLine)
    End Function
    Public Function GetIRCColor(ByVal ID As Byte) As Color
        Select Case ID
            Case 0 : Return Color.White
            Case 1 : Return Color.Black
            Case 2 : Return Color.DarkBlue
            Case 3 : Return Color.DarkGreen
            Case 4 : Return Color.Red
            Case 5 : Return Color.DarkRed
            Case 6 : Return Color.Violet
            Case 7 : Return Color.Orange
            Case 8 : Return Color.Yellow
            Case 9 : Return Color.Green
            Case 10 : Return Color.DarkCyan
            Case 11 : Return Color.Cyan
            Case 12 : Return Color.Blue
            Case 13 : Return Color.HotPink
            Case 14 : Return Color.DarkGray
            Case 15 : Return Color.LightGray
        End Select
    End Function
    Public Sub Log(ByVal Data As String, Optional ByVal Tab As String = "Raw", Optional ByVal IncludePara As Boolean = True)
        AddTab(Tab)
        Dim LogBox As WebBrowser = OpenedTabs(Tab.ToLower).Controls(0)
        LogBox.Size = Drawing.Size.Subtract(tbcLogs.Size, New Drawing.Size(14, 32))
        Dim LastWasColor As Boolean = False
        Dim LastWasBGColor As Boolean = False
        Dim ColorEnabled As Boolean = False
        Dim BGColorEnabled As Boolean = False
        Dim OpenSpans As Byte = 0
        Dim OpenFonts As Byte = 0
        Dim WhichColor As Color = Color.Black
        Dim WhichBGColor As Color = Color.White
        Dim BoldEnabled As Boolean = False
        Dim UnderlineEnabled As Boolean = False
        Dim ThisChunk As String = ""
        Dim Output As String = ""
        Dim PlainText As String = ""
        For Each Chr As Char In Data
            If Asc(Chr) = 3 Then
                LastWasColor = True
            ElseIf Asc(Chr) = 2 Then
                If BoldEnabled Then
                    Output &= "</strong>"
                Else
                    Output &= "<strong>"
                End If
                BoldEnabled = Not BoldEnabled
            ElseIf Asc(Chr) = 31 Then
                If UnderlineEnabled Then
                    Output &= "</u>"
                Else
                    Output &= "<u>"
                End If
                UnderlineEnabled = Not UnderlineEnabled
            ElseIf Asc(Chr) = 15 Then
                If BoldEnabled Then
                    Output &= "</strong>"
                    BoldEnabled = False
                End If
                If UnderlineEnabled Then
                    Output &= "</u>"
                    UnderlineEnabled = False
                End If
                ColorEnabled = False
                BGColorEnabled = False
                For i As Byte = 1 To OpenSpans
                    Output &= "</span>"
                Next
                For i As Byte = 1 To OpenFonts
                    Output &= "</font>"
                Next
                OpenSpans = 0
            ElseIf Char.IsNumber(Chr) And (LastWasColor Or LastWasBGColor) And ThisChunk.Length <= 1 Then
                ThisChunk &= Chr
            ElseIf LastWasColor And Chr = "," Then
                LastWasBGColor = True
                GoTo ColorCode
            ElseIf LastWasBGColor Then
                If ThisChunk = "" Then
                    WhichBGColor = Color.White
                Else
                    Dim BGColorID As Byte = 0
                    Byte.TryParse(ThisChunk, BGColorID)
                    WhichBGColor = GetIRCColor(BGColorID)
                End If
                ThisChunk = ""
                If BGColorEnabled Then
                    Output &= "</span>"
                    OpenSpans -= 1
                End If
                BGColorEnabled = 1
                Output &= "<span style=""background-color: " & ColorTranslator.ToHtml(WhichBGColor) & ";"">"
                LastWasBGColor = False
                OpenSpans += 1
                PlainText &= Chr
                Output &= Chr
            ElseIf LastWasColor Then
ColorCode:      If ThisChunk = "" Then
                    WhichColor = Color.Black
                Else
                    Dim ColorID As Byte = 0
                    Byte.TryParse(ThisChunk, ColorID)
                    WhichColor = GetIRCColor(ColorID)
                End If
                ThisChunk = ""
                If ColorEnabled Then
                    Output &= "</font>"
                    OpenFonts -= 1
                End If
                ColorEnabled = 1
                Output &= "<font style=""color: " & ColorTranslator.ToHtml(WhichColor) & ";"">"
                LastWasColor = False
                OpenFonts += 1
                If Not Chr = ","c Then
                    PlainText &= Chr
                    Output &= Chr
                End If
            Else
                Output &= Chr
                PlainText &= Chr
            End If
        Next
        If BoldEnabled Then
            Output &= "</strong>"
            BoldEnabled = False
        End If
        If UnderlineEnabled Then
            Output &= "</u>"
            UnderlineEnabled = False
        End If
        ColorEnabled = False
        BGColorEnabled = False
        For i As Byte = 1 To OpenSpans
            Output &= "</span>"
        Next
        For i As Byte = 1 To OpenFonts
            Output &= "</font>"
        Next
        OpenSpans = 0
        CType(OpenedTabs(Tab.ToLower).Tag, IO.StreamWriter).AutoFlush = True
        If IncludePara Then
            LogBox.Document.Body.InnerHtml &= "<p>[" & Now.ToLongTimeString & "] " & Output & "</p>" & vbNewLine
            If Not Output.Contains(Config("identpass")) Then
                CType(OpenedTabs(Tab.ToLower).Tag, IO.StreamWriter).WriteLine("<p>[" & Now.ToLongTimeString & "] " & Output & "</p>")
                If CurrentEvents.ContainsKey(Tab.ToLower) Then CurrentEvents(Tab.ToLower).WriteLine("<p>[" & Now.Subtract(EventStart(CurrentEvents(Tab))).ToString.Split(".")(0) & "] " & Output & "</p>")
            End If
        Else
            LogBox.Document.Body.InnerHtml &= "[" & Now.ToLongTimeString & "] " & Output & vbNewLine
            If Not Output.Contains(Config("identpass")) Then
                CType(OpenedTabs(Tab.ToLower).Tag, IO.StreamWriter).WriteLine("[" & Now.ToLongTimeString & "] " & Output)
                If CurrentEvents.ContainsKey(Tab.ToLower) Then CurrentEvents(Tab.ToLower).WriteLine("[" & Now.Subtract(EventStart(CurrentEvents(Tab))).ToString.Split(".")(0) & "] " & Output)
            End If
        End If
    End Sub
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Socket.Blocking = True
        tmrAntiFlood.Enabled = False
        While Socket.Connected
            Dim Buffer(Socket.ReceiveBufferSize) As Byte
            Dim Length As Integer
            Try
                Length = Socket.Receive(Buffer, Socket.Available, Net.Sockets.SocketFlags.Peek)
            Catch ex As Exception
            End Try
            If Socket.Connected = False Then
                Exit Sub
            End If
            If Length = 0 Then
                If Socket.Poll(1000, Net.Sockets.SelectMode.SelectError) Then
                    Try

                        Socket.Shutdown(Net.Sockets.SocketShutdown.Both)
                        Exit Sub
                    Catch ex As Exception
                    End Try
                End If
            End If
            Array.Resize(Buffer, Length)
            Dim Packet As String = System.Text.Encoding.ASCII.GetString(Buffer)
            If Packet.Contains(vbCrLf) Then Packet = Packet.Substring(0, Packet.IndexOf(vbCrLf) + 2)
            Length = Packet.Length
            Array.Resize(Buffer, Length)
            Try
                Socket.Receive(Buffer, Length, Net.Sockets.SocketFlags.None)
            Catch ex As Exception
            End Try
            If Socket.Connected = False Then Exit Sub
            BackgroundWorker1.ReportProgress(5, Packet)
        End While
    End Sub
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Try
            Dim Packet As String = e.UserState.ToString.TrimEnd(vbCr, vbLf)
            Packet = System.Web.HttpUtility.HtmlEncode(Packet)
            If Not String.IsNullOrEmpty(Packet) Then
                Log("<<< " & Packet)
                Dim Args() As String = Packet.Split(" ")
                Dim Command As String = Args(0)
                If Args(0).StartsWith(":") Then
                    Command = Args(1)
                    Args(0) = Args(0).TrimStart(":")
                    Packet = Packet.TrimStart(":")
                End If
                Command = Command.ToLower
                Dim Numeric As UShort = 0
                If UShort.TryParse(Command, Numeric) Then
                    Select Case Numeric
                        Case 439
                            Log("Processing connection...", "Server")
                        Case 433
                            Log("Nick is being used.", "Server")
                        Case 451
                            Log("Please register first.", "Server")
                        Case 1
                            Log("Welcome.", "Server")
                            If Capab("map") Then Send("MAP")
                            tmrAntiFlood.Enabled = True
                            If Not Capab("pass") Then Send("PRIVMSG NickServ :identify " & Config("identpass"))
                        Case 353
                            Dim Channel As String = Args(4)
                            If NickList.ContainsKey(Channel.ToLower) Then
                                NickList(Channel.ToLower).AddRange(Packet.Substring(Packet.IndexOf(":") + 1).Trim().Replace("+", "").Replace("@", "").ToLower.Split(" "))
                            End If
                            If CurrentEvents.ContainsKey(Channel.ToLower) Then
                                Dim Writer As IO.StreamWriter = CurrentEvents(Channel.ToLower)
                                Writer.WriteLine("<p style=""color:#099;"">* <strong>Users present:</strong></p>")
                                Writer.WriteLine("<p style=""color:#099;"">* " & Packet.Substring(Packet.IndexOf(":") + 1).Trim().Replace(" ", "</p><p style=""color:#099;"">* ") & "</p>")
                            End If
                        Case 6
                            If CurrentTimeStamp = Nothing Then
                                CurrentTimeStamp = Now
#If MySQL Then
                                Database.ExecuteNonQuery("INSERT INTO stat_dates (date_unix) VALUES (" & ConvertTimestamp(CurrentTimeStamp) & ")")
                                CurrentTimeStampID = Database.ExecuteScalar("SELECT date_id FROM stat_dates WHERE date_unix = " & ConvertTimestamp(CurrentTimeStamp) & " LIMIT 1")
#End If
                            End If
                            Dim Regex As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(Packet, "([a-zA-Z.]+) +\(([0-9]+)\)")
                            Dim Server As String = Regex.Groups(1).Value
                            Dim Users As Integer = Regex.Groups(2).Value
#If Chart Then

                            Dim wcEng2 As ChartEngine = tabChart2.Tag
                            Dim wcEng3 As ChartEngine = tabChart3.Tag
                            Dim slChart As Chart = wcEng3.Charts(0)
                            Dim FoundIt As Boolean = False
                            Dim Color As Color = Nothing
                            For Each DataPoint As ChartPoint In slChart.Data
                                If DataPoint.XValue = Server Then
                                    slChart.Data(slChart.Data.IndexOf(DataPoint)).YValue = Users
                                    Color = CType(slChart, PieChart).Colors(slChart.Data.IndexOf(DataPoint))
                                    FoundIt = True
                                    Exit For
                                End If
                            Next
                            If Not FoundIt Then
                                slChart.Data.Add(New ChartPoint(Server, Users))
                                Color = CType(slChart, PieChart).Colors(slChart.Data.Count - 1)
                            End If
                            Color = Drawing.Color.FromArgb(Color.A, Color.R / 1.5, Color.G / 1.5, Color.B / 1.5)
                            slChart = wcEng2.Charts.FindChart(Server)
                            If slChart Is Nothing Then
                                slChart = New SmoothLineChart()
                                slChart.Name = Server
                                wcEng2.Charts.Add(slChart)
                                slChart.Line.Color = IIf(Color = Nothing, Drawing.Color.Red, Color)
                                slChart.Legend = Server
                                slChart.ShowLineMarkers = False
                                slChart.ShowLegend = True
                                slChart.DataLabels.Visible = False
                                slChart.Shadow.Visible = True
                            End If
                            slChart.Line.Color = IIf(Color = Nothing, Drawing.Color.Red, Color)
                            slChart.Fill.Color = IIf(Color = Nothing, Drawing.Color.Red, Color)
                            slChart.Data.Add(New ChartPoint(CurrentTimeStamp.ToShortTimeString, Users))
#End If
#If MySQL Then
                            Dim ServerID As Integer = 0
                            If Database.Servers.ContainsKey(Server) Then
                                ServerID = Database.Servers(Server)
                            Else
                                Database.ExecuteNonQuery("INSERT INTO lgr_servers (server_name) VALUES (""" & Server.Replace("""", "\""") & """)")
                                ServerID = Database.ExecuteScalar("SELECT server_id FROM lgr_servers WHERE server_name = """ & Server.Replace("""", "\""") & """ LIMIT 1")
                                Database.Servers.Add(Server, ServerID)
                            End If
                            Database.ExecuteNonQuery("INSERT INTO stat_server_history (date_id, server_id, entry_users) VALUES (" & CurrentTimeStampID & ", " & ServerID & ", " & Users & ")")
#End If
                        Case 7
#If Chart Then
                            If DoneCharts Then
                                UploadCharts()
                                CurrentTimeStamp = Nothing
                                CurrentTimeStampID = Nothing
                                DoneCharts = False
                            Else
                                DoneCharts = True
                            End If
#End If
                        Case 251
                            If CurrentTimeStamp = Nothing Then
                                CurrentTimeStamp = Now
#If MySQL Then
                                Database.ExecuteNonQuery("INSERT INTO stat_dates (date_unix) VALUES (" & ConvertTimestamp(CurrentTimeStamp) & ")")
                                CurrentTimeStampID = Database.ExecuteScalar("SELECT date_id FROM stat_dates WHERE date_unix = " & ConvertTimestamp(CurrentTimeStamp) & " LIMIT 1")
#End If
                            End If
                            Dim Regex As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(Packet, "[^0-9]([0-9]+) server")
                            Dim Servers As Integer = Regex.Groups(1).Value
#If Chart Then
                            Dim wcEng As ChartEngine = tabChart1.Tag
                            Dim slChart As Chart = wcEng.Charts.FindChart("Servers")
                            slChart.Data.Add(New ChartPoint(CurrentTimeStamp.ToShortTimeString, Servers))
#End If
#If MySQL Then
                            Database.ExecuteNonQuery("INSERT INTO stat_network_history (date_id, net_server_count) VALUES (" & CurrentTimeStampID & ", " & Servers & ")")
#End If
                        Case 252
                            Dim Opers As Integer = Args(3)
#If Chart Then
                            Dim wcEng As ChartEngine = tabChart1.Tag
                            Dim slChart As Chart = wcEng.Charts.FindChart("Opers")
                            slChart.Data.Add(New ChartPoint(CurrentTimeStamp.ToShortTimeString, Opers))
#End If
#If MySQL Then
                            Database.ExecuteNonQuery("UPDATE stat_network_history SET net_oper_count = " & Opers & " WHERE date_id = " & CurrentTimeStampID & " LIMIT 1")
#End If
                        Case 254
                            Dim Channels As Integer = Args(3)
#If Chart Then
                            Dim wcEng As ChartEngine = tabChart1.Tag
                            Dim slChart As Chart = wcEng.Charts.FindChart("Channels")
                            slChart.Data.Add(New ChartPoint(CurrentTimeStamp.ToShortTimeString, Channels))
#End If
#If MySQL Then
                            Database.ExecuteNonQuery("UPDATE stat_network_history SET net_channel_count = " & Channels & " WHERE date_id = " & CurrentTimeStampID & " LIMIT 1")
#End If
                        Case 266
                            Dim Regex As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(Packet, "Global Users: ([0-9]+)")
                            Dim Users As Integer = Regex.Groups(1).Value
#If MySQL Then
                            Database.ExecuteNonQuery("UPDATE stat_network_history SET net_user_count = " & Users & " WHERE date_id = " & CurrentTimeStampID & " LIMIT 1")
#End If
#If Chart Then
                            Dim wcEng As ChartEngine = tabChart1.Tag
                            Dim slChart As Chart = wcEng.Charts.FindChart("Users")
                            slChart.Data.Add(New ChartPoint(CurrentTimeStamp.ToShortTimeString, Users))
                            If DoneCharts Then
                                UploadCharts()
                                CurrentTimeStamp = Nothing
                                CurrentTimeStampID = Nothing
                                DoneCharts = False
                            Else
                                DoneCharts = True
                            End If
#End If
                        Case Else
                            'MsgBox(Numeric & " " & Packet)
                            Log(Packet.Substring(Packet.IndexOf(":") + 1), "Server")
                    End Select
                Else
                    Select Case Command
                        Case "ping"
                            If Args.Length >= 2 Then
                                Send("PONG " & Args(1))
                            Else
                                Send("PONG")
                            End If
                        Case "notice"
                            If Not Args(1).ToLower = "auth" And Not Args(1).ToLower = MyNick.ToLower Then
                                If Args(3).StartsWith(":") Then
                                    'Log("<p style=""color:#900;"">-" & Args(0).Split("!")(0) & "- " & Packet.Substring(Packet.IndexOf(":") + 1) & "</p>", Args(2), False)
                                Else
                                    'Log("<p style=""color:#900;"">-" & Args(0).Split("!")(0) & "- " & Args(3) & "</p>", Args(2), False)
                                End If
                            End If
                        Case "mode"
                            If (Args(3) = ":+e" Or Args(3) = ":+r") And Args(2).ToLower = MyNick.ToLower Then
                                Send("JOIN " & Config("autojoin"))
                                Send("JOIN #l0gg3r")
                            ElseIf Args(2).StartsWith("#") Then
                                Log("<span style=""color:#090;"">* " & Args(0).Split("!")(0) & " sets mode: " & Packet.Substring(Packet.IndexOf(Args(3))) & "</span>", Args(2))
                            End If
                        Case "join"
                            Dim Who As String = Args(0).Split("!"c)(0)
                            Log("<span style=""color:#090;"">* Joins: " & Who & "</span>", Args(2).TrimStart(":"))
                            'Log("<span style=""color:#090;"">* Joins: " & Who & " (" & Args(0).Split("!")(1) & ")</span>", Args(2).TrimStart(":"))
                            If MyNick.ToLower = Who.ToLower Then NickList.Add(Args(2).ToLower.TrimStart(":"), New List(Of String))
                            If NickList.ContainsKey(Args(2).TrimStart(":").ToLower) Then NickList(Args(2).TrimStart(":").ToLower).Add(Who.ToLower)
                        Case "quit"
                            Dim Who As String = Args(0).Split("!"c)(0)
                            Dim PacketToSend As String = ""
                            If Args.Length >= 3 Then
                                If Args(2).StartsWith(":") Then
                                    'PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & " (" & Args(0).Split("!")(1) & ") (" & Packet.Substring(Packet.IndexOf(":") + 1) & ")</span>"
                                    PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & " (" & Packet.Substring(Packet.IndexOf(":") + 1) & ")</span>"
                                Else
                                    'PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & " (" & Args(0).Split("!")(1) & ") (" & Args(2) & ")</span>"
                                    PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & " (" & Args(2) & ")</span>"
                                End If
                            Else
                                'PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & " (" & Args(0).Split("!")(1) & ")</span>"
                                PacketToSend = "<span style=""color:#009;"">* Quits: " & Who & "</span>"
                            End If
                            For Each Channel As KeyValuePair(Of String, List(Of String)) In NickList
                                If Channel.Value.Contains(Who.ToLower) Then
                                    Log(PacketToSend, Channel.Key)
                                    NickList(Channel.Key).Remove(Who.ToLower)
                                End If
                            Next
                        Case "part"
                            Dim Who As String = Args(0).Split("!"c)(0)
                            If NickList.ContainsKey(Args(2).ToLower) Then
                                If NickList(Args(2).ToLower).Contains(Who.ToLower) Then NickList(Args(2).ToLower).Remove(Who.ToLower)
                            End If
                            If MyNick.ToLower = Who.ToLower And NickList.ContainsKey(Args(2).ToLower) Then NickList.Remove(Args(2).ToLower)
                            If Args.Length >= 4 Then
                                If Args(3).StartsWith(":") Then
                                    Log("<span style=""color:#090;"">* Parts: " & Who & " (" & Packet.Substring(Packet.IndexOf(":") + 1) & ")</span>", Args(2))
                                    'Log("<span style=""color:#090;"">* Parts: " & Who & " (" & Args(0).Split("!")(1) & ") (" & Packet.Substring(Packet.IndexOf(":") + 1) & ")</span>", Args(2))
                                Else
                                    Log("<span style=""color:#090;"">* Parts: " & Who & " (" & Args(3) & ")</span>", Args(2))
                                    'Log("<span style=""color:#090;"">* Parts: " & Who & " (" & Args(0).Split("!")(1) & ") (" & Args(3) & ")</span>", Args(2))
                                End If
                            Else
                                Log("<span style=""color:#090;"">* Parts: " & Who & "</span>", Args(2))
                                'Log("<span style=""color:#090;"">* Parts: " & Who & " (" & Args(0).Split("!")(1) & ")</span>", Args(2))
                            End If
                        Case "kick"
                            Dim WhoDoneIt As String = Args(0).Split("!"c)(0)
                            If MyNick.ToLower = Args(3).ToLower And NickList.ContainsKey(Args(2).ToLower) Then NickList.Remove(Args(2).ToLower)
                            If Args.Length >= 5 Then
                                If Args(4).StartsWith(":") Then
                                    Log("<span style=""color:#090;"">* " & Args(3) & " was kicked by " & WhoDoneIt & " (" & Packet.Substring(Packet.IndexOf(":") + 1) & ")</span>", Args(2))
                                Else
                                    Log("<span style=""color:#090;"">* " & Args(3) & " was kicked by " & WhoDoneIt & " (" & Args(4) & ")</span>", Args(2))
                                End If
                            Else
                                Log("<span style=""color:#090;"">* " & Args(3) & " was kicked by " & WhoDoneIt & "</span>", Args(2))
                            End If
                        Case "privmsg"
                            Dim Who As String = Args(0).Split("!"c)(0)
                            Dim Ident As String = Args(0).Split("!"c, "@"c)(1)
                            Dim Host As String = Args(0).Split("@"c)(1)
                            Dim RawWho As String = Who
                            Dim Color As String = ""
                            If Host.StartsWith("fullcirclemagazine") Then Color = "purple"
                            If Host.StartsWith("freenode") Or Host.ToLower.EndsWith("devnode.staff") Then Color = "red"
                            Color = NickColor(Who.ToLower, Color)
                            If Not Color = "" Then
                                Who = "<span style=""color: " & Color & ";"">" & Who & "</span>"
                            End If
                            If Host.StartsWith("fullcirclemagazine") Or Host.ToLower.EndsWith("devnode.staff") Then Who = "<strong>" & Who & "</strong>"
                            If Args(2).Contains("#") Then
                                If Packet.Contains(":") Then
                                    Dim Message As String = Packet.Substring(Packet.IndexOf(":") + 1)
                                    If Message.StartsWith("`brainfuck ") And Capab("brainfuck") Then
                                        Dim Mode As String = Args(4).ToLower
                                        Select Case Mode
                                            Case "help"
                                                Send("PRIVMSG " & Args(2) & " :brainfuck consists of ><+-[]. See this link for info: http://en.wikipedia.org/wiki/Brainfuck")
                                            Case "run"
                                                Try
                                                    Dim RawMessage As String = e.UserState.ToString.TrimEnd(vbCr, vbLf)
                                                    Dim Program As String = RawMessage.Substring(RawMessage.IndexOf(" :") + 2)
                                                    Program = Program.Substring(Program.IndexOf(" ") + 1)
                                                    Program = Program.Substring(Program.IndexOf(" ") + 1)
                                                    Dim Memory(29999) As Byte
                                                    Dim Pointer As UShort = 0
                                                    Dim NeverEndingLoop As Short = 0
                                                    Dim Output As String = ""
                                                    Dim Commands() As Char = Program.ToCharArray
                                                    For i As Integer = 0 To Commands.Length - 1
                                                        Dim CurrChr As Char = Commands(i)
                                                        Select Case CurrChr
                                                            Case ">"c
                                                                '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
                                                                If Pointer < (Memory.Length - 1) Then Pointer += 1 ' Else Pointer = 0
                                                            Case "<"c
                                                                If Pointer > 0 Then Pointer -= 1 ' Else Pointer = Memory.Length - 1
                                                            Case "+"c
                                                                If Memory(Pointer) < Byte.MaxValue Then Memory(Pointer) += 1 Else Memory(Pointer) = 0
                                                            Case "-"c
                                                                If Memory(Pointer) > Byte.MinValue Then Memory(Pointer) -= 1 Else Memory(Pointer) = Byte.MaxValue
                                                            Case "."c
                                                                Output &= Chr(Memory(Pointer))
                                                            Case ","c
                                                                ' To be implemented
                                                            Case "["c
                                                                If Memory(Pointer) = 0 Then
                                                                    Dim LoopCount As Integer = 0
                                                                    For j As Integer = i + 1 To Commands.Length - 1
                                                                        If Commands(j) = "]"c Then
                                                                            If LoopCount = 0 Then
                                                                                i = j
                                                                                GoTo LoopOk
                                                                            Else
                                                                                LoopCount -= 1
                                                                            End If
                                                                        ElseIf Commands(j) = "["c Then
                                                                            LoopCount += 1
                                                                        End If
                                                                    Next
                                                                End If
                                                            Case "]"c
                                                                NeverEndingLoop += 1
                                                                If NeverEndingLoop >= 100000 Then
                                                                    Send("PRIVMSG " & Args(2) & " :Never ending loop detected in brainfuck program.")
                                                                    GoTo StopBF
                                                                End If
                                                                Dim LoopCount As Integer = 0
                                                                For j As Integer = i - 1 To 0 Step -1
                                                                    If Commands(j) = "["c Then
                                                                        If LoopCount = 0 Then
                                                                            i = j - 1
                                                                            GoTo LoopOk
                                                                        Else
                                                                            LoopCount -= 1
                                                                        End If
                                                                    ElseIf Commands(j) = "]"c Then
                                                                        LoopCount += 1
                                                                    End If
                                                                Next
                                                                Send("PRIVMSG " & Args(2) & " :Invalid loop statement found in brainfuck program, check your ['s and ]'s.")
                                                                GoTo StopBF
LoopOk:                                                         End Select
                                                    Next
                                                    If Output = "" Then
                                                        Send("PRIVMSG " & Args(2) & " :No output from brainfuck program.")
                                                    Else
                                                        Send("PRIVMSG " & Args(2) & " :Output from brainfuck program: " & Output)
                                                    End If
                                                Catch ex As Exception
                                                    Send("PRIVMSG " & Args(2) & " :An error has occured while running the brainfuck program.")
                                                End Try
                                                Exit Select
StopBF:                                         Send("PRIVMSG " & Args(2) & " :Execution of brainfuck program was halted.")
                                        End Select

                                        '> 	increment the pointer (to point to the next cell to the right).
                                        '< 	decrement the pointer (to point to the next cell to the left).
                                        '+ 	increment (increase by one) the byte at the pointer.
                                        '- 	decrement (decrease by one) the byte at the pointer.
                                        '. 	output the value of the byte at the pointer.
                                        ', 	accept one byte of input, storing its value in the byte at the pointer.
                                        '[ 	jump forward to the command after the corresponding ] if the byte at the pointer is zero.
                                        '] 	jump back to the command after the corresponding [ if the byte at the pointer is nonzero.> 	++ptr;

                                        '< 	--ptr;
                                        '+ 	++(*ptr);
                                        '- 	--(*ptr);
                                        '. 	putchar(*ptr);
                                        ', 	*ptr=getchar();
                                        '[ 	while (*ptr) {
                                        '] 	}

                                    ElseIf Message.StartsWith("`validate ") And Capab("htmlvalidate") Then
                                        Message = Message.Substring(Message.IndexOf(" ") + 1)
                                        Dim Content As String = New System.Net.WebClient().DownloadString("http://validator.w3.org/check?uri=" & System.Web.HttpUtility.UrlEncode(Message) & "&charset=%28detect+automatically%29&doctype=Inline&group=0")
                                        If Content.Contains("<h3 id=""congrats"">Congratulations</h3>") Then
                                            Send("PRIVMSG " & Args(2) & " :Site is syntax-wise valid.")
                                        Else
                                            Send("PRIVMSG " & Args(2) & " :Site is syntax-wise INVALID.")
                                        End If
                                        'Send("PRIVMSG " & Args(2) & " :Site is syntax-wise " & IIf(New System.Net.WebClient().DownloadString("http://validator.w3.org/check?uri=" & System.Web.HttpUtility.UrlEncode(Message.Substring(Message.IndexOf(" ") + 1)) & "&charset=%28detect+automatically%29&doctype=Inline&group=0").Contains("<h3 id=""congrats"">Congratulations</h3>"), "valid!", "INVALID."))
                                    ElseIf Message.StartsWith("`webui ") And (Host = "unaffiliated/danopia/bot/danobot" Or Host = "danopia.unaffiliated.bot" Or Host = Config("admin")) Then
                                        Dim Mode As String = Args(4).ToLower
                                        Select Case Mode
                                            Case "colorlist"
                                                Dim Matches As Xml.XmlNodeList = XMLSettings.SelectNodes("config/colors/color")
                                                Dim Colors As New List(Of String)
                                                For Each Node As Xml.XmlNode In Matches
                                                    If Node.InnerText.ToLower.EndsWith(";font-style:italic") Then
                                                        If Not Colors.Contains(Node.InnerText.Substring(0, Node.InnerText.ToLower.IndexOf(";font-style:italic")).ToLower) Then Colors.Add(Node.InnerText.Substring(0, Node.InnerText.ToLower.IndexOf(";font-style:italic")).ToLower)
                                                    Else
                                                        If Not Colors.Contains(Node.InnerText.ToLower) Then Colors.Add(Node.InnerText.ToLower)
                                                    End If
                                                Next
                                                Send("PRIVMSG #l0gg3r :`webuiresponse colorlist " & Join(Colors.ToArray, " "))
                                            Case "colorrequest"
                                                Dim Nick As String = Args(5)
                                                Dim NewColor As String = Args(6).ToLower
                                                Dim IsBot As Boolean = Boolean.Parse(Args(7))
                                                Dim Owner As String = ""
                                                If IsBot Then Owner = Args(8)
                                                Dim MD5er As New System.Security.Cryptography.MD5CryptoServiceProvider()
                                                Dim Code As String = Convert.ToBase64String(MD5er.ComputeHash(System.Text.Encoding.ASCII.GetBytes(Nick & NewColor & IsBot & Rnd())))
                                                Send("PRIVMSG #l0gg3r :A WebUI user requested that " & Nick & "'s nick color in the logs be changed to " & NewColor & IIf(IsBot, ";font-style:italic", "") & ". I have PMed him a code to send back (" & Code & "), or just say `approve " & Code)
                                                Send("PRIVMSG " & Nick & " :Say """ & Code & """ without the quotes back to me to make that your color in my logs.")
                                                ColorRequests.Add(Code, New ColorRequest(Nick, Nick.ToLower, Color, IsBot, Owner, Owner.ToLower()))
                                        End Select
                                    ElseIf Message = "`meep" And (Host = Config("admin") Or Args(2).ToLower = "#meep" Or Args(2).ToLower = "#flood") And Capab("meepnet") Then
                                        Send("PRIVMSG " & Args(2) & " :meep")
                                    ElseIf Message.StartsWith("`approve ") And Host = Config("admin") Then
                                        XMLSettings.Load(XMLPath)
                                        'Dim Nick As String = Args(5).ToLower
                                        'Dim NewColor As String = Args(6).ToLower
                                        'Dim Matches As Xml.XmlNodeList = XMLSettings.SelectNodes("config/colors/color[@nick='" & Nick & "']")
                                        'If Matches.Count > 0 Then
                                        '    'Matches(0).InnerText=
                                        'Else
                                        '    'Return DefaultColor
                                        'End If
                                        'nickcolor
                                        XMLSettings.Load(XMLPath)
                                    ElseIf Message.StartsWith("`weather ") And Capab("weather") Then
                                        Send("PRIVMSG " & Args(2) & " :" & Weather.GrabCurrent(Message.Substring(Message.IndexOf(" ") + 1)))
                                    ElseIf Message.StartsWith("`cweather ") And Capab("weather") Then
                                        Send("PRIVMSG " & Args(2) & " :" & Weather.GrabCurrentC(Message.Substring(Message.IndexOf(" ") + 1)))
                                    ElseIf Message = "`reload" And Host = Config("admin") Then
                                        XMLSettings.Load(XMLPath)
                                        Send("PRIVMSG " & Args(2) & " :Config file reloaded.")
                                    ElseIf Message.StartsWith("`start ") And (Host.ToLower.EndsWith(".devnode.staff") Or Host.StartsWith("fullcirclemagazine") Or Host = Config("admin")) And Capab("specialevents") Then
                                        If CurrentEvents.ContainsKey(Args(2).ToLower) Then
                                            Send("PRIVMSG " & Args(2) & " :There is already an event going on.")
                                        Else
                                            Dim Path As String = String.Format(IO.Path.Combine(My.Application.Info.DirectoryPath, Config("slogpath")), Args(2).TrimStart("#")) & IO.Path.GetFileName(Message.Substring(Message.IndexOf(" ") + 1)).ToLower & "." & Config("extension")
                                            If IO.File.Exists(Path) Then
                                                Send("PRIVMSG " & Args(2) & " :Special event log already exists.")
                                            Else
                                                Dim Dirs() As String = Path.Substring(3, Path.LastIndexOfAny(New Char() {"/"c, "\"c}) - 3).Split("/"c, "\"c)
                                                Dim Dir As String = Path.Substring(0, 2)
                                                For Each SubDir As String In Dirs
                                                    Dir &= "/" & SubDir
                                                    If Not IO.Directory.Exists(Dir) Then IO.Directory.CreateDirectory(Dir)
                                                Next
                                                Dim EventWriter As New IO.StreamWriter(Path, False)
                                                EventWriter.AutoFlush = True
                                                EventWriter.WriteLine("<html><head><title>IRC Log from " & Args(2) & " (Special Event) - Captured by " & Config("nick") & "</title><style>" & Config("filecss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & Args(2) & " (Special Event) and logged by " & Config("nick") & "</p>" & vbNewLine & _
                                                "<p style=""color:#090;"">* Special event log requested by " & Who & "</p>" & vbNewLine & _
                                                "<p style=""color:#090;"">* Timestamps are relative to now</p>")
                                                EventStart.Add(EventWriter, Now)
                                                CurrentEvents.Add(Args(2).ToLower, EventWriter)
                                                Send("PRIVMSG " & Args(2) & " :Special event logging started, logging to filename " & IO.Path.GetFileName(Path))
                                                Send("NAMES " & Args(2))
                                            End If
                                        End If
                                    ElseIf Message.StartsWith("`end") And (Host.ToLower.EndsWith(".devnode.staff") Or Host.StartsWith("fullcirclemagazine")) And Capab("specialevents") Then
                                        If CurrentEvents.ContainsKey(Args(2).ToLower) Then
                                            Dim EventWriter As IO.StreamWriter = CurrentEvents(Args(2).ToLower)
                                            EventWriter.WriteLine("<p style=""color:#090;"">* Special event logging stopped (" & Now.ToLongTimeString & ") by " & Who & "</p></body></html>")
                                            EventWriter.Close()
                                            EventStart.Remove(EventWriter)
                                            CurrentEvents.Remove(Args(2).ToLower)
                                            Send("PRIVMSG " & Args(2) & " :Special event logging stopped.")
                                        Else
                                            Send("PRIVMSG " & Args(2) & " :What event?")
                                        End If
                                    ElseIf Message = "`color" Then
                                        Send("PRIVMSG " & Args(2) & " :" & RawWho & ", your nick is HTML color """ & IIf(Color = "", "black", Color) & """ in my logs.")
                                    ElseIf Message = "`setcolor" And Host = Config("admin") Then
                                        Send("PRIVMSG " & Args(2) & " :" & RawWho & ", your nick is HTML color """ & IIf(Color = "", "black", Color) & """ in my logs.")
                                    End If
                                    If Message.StartsWith(Chr(1) & "ACTION ") Then
                                        Message = Message.Substring(8).TrimEnd(Chr(1))
                                        Log("<span style=""color:purple;"">* " & Who & " " & Message & "</span>", Args(2))
                                    ElseIf Message.StartsWith(Chr(1)) Then
                                        Message = Message.Trim(Chr(1))
                                        If Message.Contains(" ") Then
                                            Log("<span style=""color:red;"">[" & Who & ":" & Args(2) & " " & Message.Split(" ")(0) & "] " & Message.Substring(Message.IndexOf(" ") + 1) & "</span>", Args(2))
                                        Else
                                            Log("<span style=""color:red;"">[" & Who & ":" & Args(2) & " " & Message & "]</span>", Args(2))
                                        End If
                                    Else
                                        Log("&lt;" & Who & "&gt; " & Message, Args(2))
                                    End If
                                Else
                                    Log("&lt;" & Who & "&gt; " & Args(3), Args(2))
                                End If
                            Else
                                If Packet.Contains(":") Then
                                    Log("&lt;" & Who & "&gt; " & Packet.Substring(Packet.IndexOf(":") + 1), RawWho)
                                Else
                                    Log("&lt;" & Who & "&gt; " & Args(3), RawWho)
                                End If
                            End If
                        Case "nick"
                            Dim Who As String = Args(0).Split("!"c)(0)
                            If MyNick.ToLower = Who.ToLower Then MyNick = Args(2).Substring(1)
                            For Each Channel As KeyValuePair(Of String, List(Of String)) In NickList
                                If Channel.Value.Contains(Who.ToLower) Then
                                    Log("<span style=""color:#090;"">* " & Who & " is now known as " & Args(2).Substring(1) & "</span>", Channel.Key)
                                    NickList(Channel.Key).Remove(Who.ToLower)
                                    NickList(Channel.Key).Add(Args(2).Substring(1).ToLower)
                                End If
                            Next
                        Case "error"
                            Log("<span style=""color:#f00;"">* " & Packet.Substring(Packet.IndexOf(":") + 1) & "</p>", "Error")
                            Socket.Close()
                        Case Else
                    End Select
                End If
            End If
        Catch ex As Exception
        End Try
    End Sub
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        Log("Loop done.")
    End Sub
    Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        If Not String.IsNullOrEmpty(txtToSend.Text) Then
            Send(txtToSend.Text)
        End If
    End Sub
    Private Sub tsbConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbConnect.Click
        If Not Socket.Connected Then
            MyNick = Config("nick")
            Socket = New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
            Socket.Connect(Config("server"), UShort.Parse(Config("port")))
            Send("PASS " & Config("identpass"))
            Send("NICK " & Config("nick"))
            Send("USER " & Config("nick") & " localhost 0.0.0.0 :" & Config("description"))
            If Not BackgroundWorker1.IsBusy Then BackgroundWorker1.RunWorkerAsync()
        End If
        If Not Database.IsConnected Then Database.Connect()
    End Sub
    Private Sub tsbDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbDisconnect.Click
        If Socket.Connected Then
            Send("QUIT :" & Config("defaultquit"))
            Socket.Close()
        End If
    End Sub
    Private Sub tsbSaveLog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbSaveLog.Click
        If tbcLogs.TabCount > 0 Then
            sfd.FileName = tbcLogs.SelectedTab.Text & "." & Config("extension")
            sfd.FilterIndex = 1
            If sfd.ShowDialog() = Windows.Forms.DialogResult.OK Then
                My.Computer.FileSystem.WriteAllText(sfd.FileName, CType(tbcLogs.SelectedTab.Controls(0), WebBrowser).Document.GetElementsByTagName("html")(0).OuterHtml(), False)
            End If
        End If
    End Sub
    Private Sub tsbClearLog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbClearLog.Click
        If tbcLogs.TabCount > 0 Then
            CType(tbcLogs.SelectedTab.Controls(0), WebBrowser).Navigate("about:blank")
            CType(tbcLogs.SelectedTab.Controls(0), WebBrowser).Document.Write("<html><head><title>IRC Log from " & tbcLogs.SelectedTab.Text & " - Captured by " & Config("nick") & "</title><style>" & Config("screencss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & tbcLogs.SelectedTab.Text & " and logged by " & Config("nick") & "</p>" & vbNewLine & "</body></html>")
            CType(tbcLogs.SelectedTab.Controls(0), WebBrowser).DocumentText = "<html><head><title>IRC Log from " & tbcLogs.SelectedTab.Text & " - Captured by " & Config("nick") & "</title><style>" & Config("screencss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & tbcLogs.SelectedTab.Text & " and logged by " & Config("nick") & "</p>" & vbNewLine & "</body></html>"
        End If
    End Sub
    Private Sub tsbCloseWindow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbCloseWindow.Click
        If tbcLogs.TabCount > 0 Then
            Dim Result As MsgBoxResult = MsgBox("Do you want to save this log before you close it?", MsgBoxStyle.Question Or MsgBoxStyle.YesNoCancel)
            If Result = MsgBoxResult.Cancel Then Exit Sub
            If Result = MsgBoxResult.Yes Then
                tsbSaveLog_Click(sender, e)
            End If
            tbcLogs.TabPages.Remove(tbcLogs.SelectedTab)
        End If
    End Sub
    Private Sub tmrReloadXML_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrReloadXML.Tick
        XMLSettings.Load(XMLPath)
        Dim ThisMoment As New Date(Now.Year, Now.Month, Now.Day)
        For Each Tab As TabPage In tbcLogs.TabPages
            If TypeOf Tab.Tag Is IO.StreamWriter Then
                CType(Tab.Controls(0), WebBrowser).Navigate("about:blank")
                CType(Tab.Controls(0), WebBrowser).Document.Write("<html><head><title>IRC Log from " & Tab.Text & " - Captured by " & Config("nick") & "</title><style>" & Config("screencss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & Tab.Text & " and logged by " & Config("nick") & "</p>" & vbNewLine & "</body></html>")
                CType(Tab.Controls(0), WebBrowser).DocumentText = "<html><head><title>IRC Log from " & Tab.Text & " - Captured by " & Config("nick") & "</title><style>" & Config("screencss") & "</style></head><body>" & vbNewLine & "<p>Log started " & Now.ToLongDateString & " @ " & Now.ToLongTimeString & " on " & Config("server") & " " & Tab.Text & " and logged by " & Config("nick") & "</p>" & vbNewLine & "</body></html>"
            End If
        Next
        If ThisMoment > CurrentDate Then
            For Each Tab As TabPage In tbcLogs.TabPages
                If TypeOf Tab.Tag Is IO.StreamWriter Then
                    CType(Tab.Tag, IO.StreamWriter).WriteLine("</body></html>")
                    CType(Tab.Tag, IO.StreamWriter).Close()
                    Tab.Tag = OpenWriter(Tab.Text)
                 End If
            Next
            CurrentDate = ThisMoment
        End If
    End Sub
    Private Sub tmrAntiFlood_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrAntiFlood.Tick
        If AntiFlood > 0 Then AntiFlood -= 1 Else AntiFlood = 0
    End Sub
    Private Sub tmrStats_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrStats.Tick
#If Chart Then
        DoneCharts = False
#End If
        If Capab("stats") Then
            Send("LUSERS")
            If Capab("map") Then Send("MAP")
        End If
    End Sub
    Private Sub tsbRefreshGraphs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbRefreshGraphs.Click
        tmrStats_Tick(sender, e)
    End Sub
End Class